package com.me.myFramework.myAop.aop120;

import com.me.myFramework.myAop.aop120.advice.Advice;
import com.me.myFramework.myAop.aop120.advice.method.AfterReturningAdvice;
import com.me.myFramework.myAop.aop120.advice.method.MethodBeforeAdvice;
import com.me.myFramework.myAop.aop120.intercept.method.AfterReturningAdviceInterceptor;
import com.me.myFramework.myAop.aop120.intercept.method.MethodBeforeAdviceInterceptor;
import com.me.myFramework.myAop.aop120.intercept.method.MethodInterceptor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 把 模板方法 和 用户自定义的增强逻辑彻底分离开，同时需要另外定义一个容器（ProxyFactory）接收 用户定义的增强逻辑、目标对象
 */
public class ProxyFactory {

    private Object target;

    private Advice advice;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // TODO 从模板方法中进一步抽取 advice接口
                MethodInterceptor interceptor = advice2Interceptor(advice);
                return interceptor.invoke(method, args, target);
            }
        });
    }

    private MethodInterceptor advice2Interceptor(Advice advice) {
        if (advice instanceof MethodBeforeAdvice) {
            return new MethodBeforeAdviceInterceptor((MethodBeforeAdvice) advice);
        }
        else if (advice instanceof AfterReturningAdvice) {
            return new AfterReturningAdviceInterceptor((AfterReturningAdvice) advice);
        }
        else {
            throw new RuntimeException("未知的 advice 类型");
        }
    }

    public Advice getAdvice() {
        return advice;
    }

    public void setAdvice(Advice advice) {
        this.advice = advice;
    }

}
